#!/usr/bin/env ruby
# wxRuby2 Sample Code. Copyright (c) 2004-2008 wxRuby development team
# Freely reusable code: see SAMPLES-LICENSE.TXT for details

lib = File.expand_path(File.dirname(__FILE__))
$LOAD_PATH.unshift lib unless $LOAD_PATH.include?(lib)

begin
  require 'rubygems' 
rescue LoadError
end
require 'wx'



require 'thread' # For Thread and Mutex
require 'socket' # For TCP/IP Communications
require 'cloudi/client_info'
require 'cloudi/socket_packet' # For simplfying Socket communciation
require 'cloudi/server_socket'
require 'cloudi/switcher.rb'


class MyCanvas < Wx::ScrolledWindow
  include Socket::Constants
  ID_START = 1001
  ID_STOP = 1002
  ID_NAME = 1003
  ID_EXIT = 1004
  ID_TIMER_POLL = 1005

  
  def initialize(parent, id=-1, size=Wx::DEFAULT_SIZE)
    super(parent, -1, Wx::Point.new(0,0), size, Wx::SUNKEN_BORDER)
    @lines = []
    @maxWidth = 1000
    @maxHeight = 1000
    @x = @y = 0
    @curLine = []
    @drawing = false
    
    @ports_created = false
    
    @timer = Wx::Timer.new(self,ID_TIMER_POLL)
        
    set_background_colour(Wx::WHITE) 
        
    set_cursor(Wx::Cursor.new(Wx::CURSOR_PENCIL))
    
    Cloudi::Detail.new(self)
    
    set_scrollbars(20, 20, @maxWidth / 20, @maxHeight / 20, 0, 0, true)
        
    evt_left_down {|event| on_left_button_event_down(event)}
    evt_left_up {|event| on_left_button_event_up(event)}
    evt_motion {|event| on_left_button_event_motion(event)}
    evt_paint { on_paint }
    evt_timer(ID_TIMER_POLL) { Thread.pass }
    #evt_mousewheel {|event| on_wheel(event)}
    
    # DRb.start_service "druby://127.0.0.1:8090", self
    
    @server_socket = Cloudi::ServerSocket.new(self, 8090, @timer)
    @server_socket.start
  rescue => excep
    puts excep
    puts excep.backtrace.join("\n")
  end
    
  def on_paint
    paint { | dc | do_drawing(dc) }
  end
    
  def do_drawing(dc, printing=false)
    # Reset the origin co-ordinates of the DC to reflect current scrolling
    do_prepare_dc(dc)
    
    sw = Cloudi::Switcher.new(dc, 8, 8)
    
    unless @ports_created
      8.times do |i|
        Cloudi::LeftPort.new(self, dc, sw, i, (i + 8).to_s)
        Cloudi::RightPort.new(self, dc, sw, i, i.to_s)
      end
    end
    
    @ports_created = true
      
    Cloudi::Line.draw(dc)
    
    #Cloudi::Line.new(dc, @p1, @p2)
    #Cloudi::Line.new(dc, @p1, @p3)
  end
  
  def connect_ports(from, to)
    Cloudi::Line.new(from, to)
  end
    
  def draw_saved_lines(dc)
    dc.set_pen(Wx::Pen.new("MEDIUM FOREST GREEN", 4, Wx::SOLID))
    @lines.each do |line|
      line.each do |coords|
        coords.flatten!()
        dc.draw_line(coords[0], coords[1], coords[2], coords[3])
      end
    end
  end
    
  def set_XY(event)
    @x, @y = convert_event_coords(event)
  end
    
  def convert_event_coords(event)
    xView, yView = get_view_start()
    xDelta, yDelta = get_scroll_pixels_per_unit()
    return event.get_x() + (xView * xDelta), event.get_y() + (yView * yDelta)
  end
    
  def on_left_button_event_down(event)
    if event.left_is_down() and !@drawing
      set_focus()
      set_XY(event)
      @event_x_old =  event.get_x # added this to save the current absolute...
      @event_y_old = event.get_y  # ... mouse position
      @curLine = []
      capture_mouse()
      @drawing = true
    end
  end
    
  def on_left_button_event_up(event)
    if !event.left_is_down() and @drawing
      @lines.push(@curLine)
      @curLine = []
      release_mouse()
      @drawing = false
    end
  end
    
  def on_left_button_event_motion(event)
    if event.left_is_down() and @drawing
      #             if $BUFFERED
      #                 # If doing buffered drawing, create the buffered DC, giving it
      #                 # it a real DC to blit to when done.
      #                 cdc = Wx::ClientDC.new(self)
      #                 dc = Wx::BufferedDC.new(cdc, @buffer)
      #             else
      #                 dc = Wx::ClientDC.new(self)
      #             end

      paint do | dc |
        dc.set_pen(Wx::Pen.new("MEDIUM FOREST GREEN", 4, Wx::SOLID))
        save_coords = [@x, @y] + convert_event_coords(event)             # translate the absolute coords to save them in the array
        coords = [@event_x_old, @event_y_old, event.get_x, event.get_y]  # the absolute coords to use for the first draw
        @curLine.push(save_coords)                                       # use the translated coords here
        coords.flatten!()
        dc.draw_line(coords[0], coords[1], coords[2], coords[3])         # and the absolute coords here
        set_XY(event)
        @event_x_old = event.get_x                                       # saving the new ...
        @event_y_old = event.get_y                                       # ... absolute coords
      end
    end
  end
    
end

module Demo
  def Demo.run(frame, nb, log)
    win = MyCanvas.new(nb, log)
    return win
  end
    
  def Demo.overview
    return "The wxScrolledWindow class manages scrolling for its client area, transforming the coordinates according to the scrollbar positions, and setting the scroll positions, thumb sizes and ranges according to the area in view."
  end
end


class AuiFrame < Wx::Frame
  def initialize(*args)
    super
    MyCanvas.new(self)
  end
end
  
class AuiDemoApp < Wx::App
  def on_init
    frame = AuiFrame.new( nil, Wx::ID_ANY, "Wx::AUI Sample Application",
      Wx::DEFAULT_POSITION,
      Wx::Size.new(800, 600) )
    set_top_window(frame)
    frame.show
    return true
  end
end

AuiDemoApp.new.main_loop()